'/
' Fetherquest Online
' 
' =========================================================================
' 
' This program is free software: you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation, either version 3 of the License, or
' (at your option) any later version.
' 
' This program is distributed in the hope that it will be useful,
' but WITHOUT ANY WARRANTY; without even the implied warranty of
' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
' GNU General Public License for more details.
' 
' You should have received a copy of the GNU General Public License
' along with this program.  If not, see <http://www.gnu.org/licenses/>.
'/

type BasePeer extends Base

	'// -------------------------------------------------------------------------------------------------------------
	'// 
	'// -------------------------------------------------------------------------------------------------------------
	method update() abstract;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Initialize the peer.
	'// -------------------------------------------------------------------------------------------------------------
	method init()
	
		m_rakPeer = TRKRakNetworkFactory.GetRakPeerInterface();
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// Deinitialize the peer.
	'// -------------------------------------------------------------------------------------------------------------
	method deinit()
	
		m_rakPeer.Shutdown(m_shutdownTime);
		TRKRakNetworkFactory.DestroyRakPeerInterface(m_rakPeer);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------------
	'// Send a message to another peer.
	'// Packet channel example: You have chatmessages on channel 1, and movement on channel 2. This means they are ordered
	'// and sent seperately. The packets on channel 1 will not be ordered with the packets on channel 2.
	'// 
	'// (string) msg: The actual message to send.
	'// (int) packetChannel: Which channel to send the packet to.
	'// (TRKSystemAddress) targetAddr: The system address of the target (the guy we send this message to).
	'// -------------------------------------------------------------------------------------------------------------------
	method sendMessageToPeer(msg:string, packetChannel:int, targetAddr:TRKSystemAddress)
	
		local message:byte ptr = msg.toCString();
		m_rakPeer.Send(message, msg.length + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, targetAddr, false);
		memFree(message);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------------
	'// Send a message to all connected peers.
	'// 
	'// (string) msg: The actual message to send.
	'// (int) packetChannel: Which channel to send the packet to.
	'// -------------------------------------------------------------------------------------------------------------------
	method sendMessageToAll(msg:string, packetChannel:int)
	
		local message:byte ptr = msg.toCString();
		m_rakPeer.Send(message, msg.length + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, UNASSIGNED_SYSTEM_ADDRESS, true);
		memFree(message);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------------
	'// Send a message to all connected peers but one.
	'// 
	'// (string) msg: The actual message to send.
	'// (int) packetChannel: Which channel to send the packet to.
	'// (TRKSystemAddress) exception: The system address of the system we DON'T want to send the message to.
	'// -------------------------------------------------------------------------------------------------------------------
	method sendMessageToAllButOne(msg:string, packetChannel:int, exception:TRKSystemAddress)
	
		local message:byte ptr = msg.toCString();
		m_rakPeer.Send(message, msg.length + 1, HIGH_PRIORITY, RELIABLE_ORDERED, 0, exception, true);
		memFree(message);
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Return a random port.
	'// -----------------------------------------------------------------------------------------------------------------
	method getRandomPort:short()
	
		return rand(22000, 27400);
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Return the hostname of the local system. The Local System is the system the application running RabNet was
	'// launched on. It does not rely on any internal objects, but on system information from the OS.
	'// -----------------------------------------------------------------------------------------------------------------
	method getLocalSystemHostName:string()
	
		return hostname(hostip("localhost", 0));
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Return the local IP address of the local system.
	'// -----------------------------------------------------------------------------------------------------------------
	method getLocalSystemInternalIP:string()
	
		return hostip("localhost", 0);
	
	end method
	
	'// -----------------------------------------------------------------------------------------------------------------
	'// Return the remote ip address of a specific host name on the internet.
	'// 
	'// (string) host_name: The name of the host from which we wish to retrieve an ip address.
	'// -----------------------------------------------------------------------------------------------------------------
	method getRemoteIPFromHostName:int(host_name:string)
	
		return hostip(host_name);
	
	end method
	
	'// -------------------------------------------------------------------------------------------------------------
	'// 0 = BasePeer, 1 = MasterPeer, 2 = ServerPeer
	'// -------------------------------------------------------------------------------------------------------------
	field m_peerType:short = 0;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// 
	'// -------------------------------------------------------------------------------------------------------------
	field m_connected:byte = false;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// 
	'// -------------------------------------------------------------------------------------------------------------
	field m_rakPeer:TRKRakPeerInterface = null;

	'// -------------------------------------------------------------------------------------------------------------
	'// 
	'// -------------------------------------------------------------------------------------------------------------
	field m_thisSysAddr:TRKSystemAddress = null;

	'// -------------------------------------------------------------------------------------------------------------
	'// 
	'// -------------------------------------------------------------------------------------------------------------
	field m_conSysAddr:TRKSystemAddress = null;
	
	'// -------------------------------------------------------------------------------------------------------------
	'// The time the peer waits to send and recieved unsent or unrecieved packets before shutting down.
	'// -------------------------------------------------------------------------------------------------------------
	field m_shutdownTime:int = 1000;

end type
